package com.koi.system.controller.dept;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.koi.common.anno.KoiDeptDataScope;
import com.koi.common.anno.KoiLog;
import com.koi.common.constants.KoiConstants;
import com.koi.common.enums.log.OperType;
import com.koi.common.ex.koi.YUtil;
import com.koi.common.satoken.KoiLoginUtil;
import com.koi.model.bo.element.CascaderStringBo;
import com.koi.model.vo.system.SysDeptVo;
import com.koi.pojo.system.SysDept;
import com.koi.system.service.dept.SysDeptService;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author ･ᴗ･
 * @description [部门表-控制层]
 */
@Validated
@RequestMapping("/koi")
@RequiredArgsConstructor
@RestController
public class SysDeptController {

    private final SysDeptService sysDeptService;

    /* 注意：分配部门选项框加上是否拥有所有部门数据权限 */

    /**
     * @description [分页查询]
     * @author ･ᴗ･
     */
    @SaCheckPermission("system:dept:list")
    @GetMapping("/sysDept/listPage")
    public IPage<SysDept> listPage(SysDeptVo vo) {
        // 分页构造器
        Page<SysDept> page = new Page<>(vo.getPageNo(), vo.getPageSize());
        // 条件构造器
        LambdaQueryWrapper<SysDept> wrapper = new LambdaQueryWrapper<>();
        // 进行分页查询
        page = sysDeptService.page(page, wrapper);
        return page;
    }

    /**
     * @description [查询分配当前用户的部门数据]
     * @author ･ᴗ･
     */
    @KoiDeptDataScope(deptAlias = "t1")
    @GetMapping("/sysDept/list")
    public List<SysDept> list(SysDeptVo vo) {
        return sysDeptService.listSysDept(vo);
    }

    /**
     * @description [查询一个]
     * @author ･ᴗ･
     */
    @GetMapping("/sysDept/getById/{id}")
    public SysDept getById(@PathVariable Long id) {
        return sysDeptService.getById(id);
    }

    /**
     * @description [新增]
     * @author ･ᴗ･
     */
    @KoiLog(title = "新增部门", operType = OperType.ADD)
    @SaCheckPermission("system:dept:add")
    @PostMapping("/sysDept/add")
    public void add(@Validated @RequestBody SysDept sysDept) {
        // 条件构造器
        LambdaQueryWrapper<SysDept> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDept::getDeptId, sysDept.getDeptId());
        SysDept dept = sysDeptService.getOne(wrapper);
        YUtil.isTrue(ObjectUtils.isNotEmpty(dept), "该部门编号已存在");
        if (StringUtils.isNotBlank(KoiLoginUtil.getUserName())) {
            sysDept.setCreateBy(KoiLoginUtil.getUserName());
        }
        YUtil.isTrue(!sysDeptService.save(sysDept), "新增失败，请稍后重试");
    }

    /**
     * @description [修改]
     * @author ･ᴗ･
     */
    @KoiLog(title = "修改部门", operType = OperType.UPDATE)
    @SaCheckPermission("system:dept:update")
    @PostMapping("/sysDept/update")
    public void update(@Validated @RequestBody SysDept sysDept) {
        // 条件构造器
        LambdaQueryWrapper<SysDept> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDept::getDeptId, sysDept.getDeptId());
        long number = sysDeptService.count(wrapper);
        if (number == 1L) {
            SysDept dept = sysDeptService.getOne(wrapper);
            YUtil.isTrue(ObjectUtils.isNotEmpty(dept) && dept.getDeptId().equals(sysDept.getParentId()), "不能选择自己为上级部门");
            YUtil.isTrue(ObjectUtils.isNotEmpty(dept) && !dept.getId().equals(sysDept.getId()), "该部门编号已存在");
        }
        if (number == 0L) {
            YUtil.isTrue("请选择需要修改的部门");
        }
        if (number > 1L) {
            YUtil.isTrue("请联系管理员检查部门编码存在多个重复");
        }
        if (StringUtils.isNotBlank(KoiLoginUtil.getUserName())) {
            sysDept.setUpdateBy(KoiLoginUtil.getUserName());
        }
        YUtil.isTrue(!sysDeptService.updateById(sysDept), "修改失败，请稍后重试");
    }

    /**
     * @description [删除]
     * @author ･ᴗ･
     */
    @KoiLog(title = "删除部门", operType = OperType.DELETE)
    @SaCheckPermission("system:dept:delete")
    @PostMapping("/sysDept/deleteById/{id}")
    public void delete(@PathVariable Long id) {
        SysDept dept = sysDeptService.getById(id);
        LambdaQueryWrapper<SysDept> wrapper = new LambdaQueryWrapper<>();
        if (ObjectUtils.isNotEmpty(dept) && StringUtils.isNotBlank(dept.getDeptId())) {
            wrapper.eq(SysDept::getParentId, dept.getDeptId());
            long number = sysDeptService.count(wrapper);
            YUtil.isTrue(number > 0L, "请先删除此节点的下级数据");
            YUtil.isTrue(!sysDeptService.removeById(id), "删除失败，请稍后重试");
        } else {
            YUtil.isTrue("请选择需要删除的数据");
        }

    }

    /**
     * @description [批量删除]
     * @author ･ᴗ･
     */
    @KoiLog(title = "批量删除部门", operType = OperType.DELETE)
    @SaCheckPermission("system:dept:delete")
    @PostMapping("/sysDept/batchDelete")
    public void delete(@NotNull(message = "请选择需要删除的数据") @RequestBody List<Long> ids) {
        YUtil.isTrue(!sysDeptService.removeByIds(ids), "删除失败，请稍后重试");
    }

    /**
     * @description [修改状态]
     * @author ･ᴗ･
     */
    @SaCheckPermission("system:dept:update")
    @PostMapping("/sysDept/updateStatus/{id}/{deptStatus}")
    public void updateStatus(@PathVariable("id") Long id, @PathVariable("deptStatus") String deptStatus) {
        UpdateWrapper<SysDept> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("dept_status", deptStatus).eq("id", id);
        YUtil.isTrue(!sysDeptService.update(null, updateWrapper), "修改失败，请稍后重试");
    }

    /**
     * @description [是否展开]
     * @author ･ᴗ･
     */
    @SaCheckPermission("system:dept:update")
    @PostMapping("/sysDept/updateSpread/{id}/{isSpread}")
    public void updateSpread(@PathVariable("id") Long id, @PathVariable("isSpread") String isSpread) {
        UpdateWrapper<SysDept> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("is_spread", isSpread).eq("id", id);
        YUtil.isTrue(!sysDeptService.update(null, updateWrapper), "修改失败，请稍后重试");
    }

    /**
     * @description [部门级联下拉框]
     * @author ･ᴗ･
     */
    @GetMapping("/sysDept/cascaderList")
    public List<CascaderStringBo> cascaderList() {
        return sysDeptService.cascaderList();
    }

    /**
     * @description [查询所有正常的路由 AND 展开节点（角色分配部门权限使用）]
     * @author ･ᴗ･
     */
    @KoiDeptDataScope(deptAlias = "t1")
    @GetMapping("/sysDept/listDeptNormal")
    public Map<String, Object> listDeptNormal(SysDeptVo sysDeptVo) {
        Map<String, Object> map = new HashMap<>();
        // 部门正常数据
        /* 如果不进行权限数据筛选，则上边一行注释，下边注释解开 */
        List<SysDept> deptList = sysDeptService.listDeptNormal(sysDeptVo);
        // LambdaQueryWrapper<SysDept> wrapper = new LambdaQueryWrapper<>();
        // wrapper.select(SysDept::getDeptId, SysDept::getDeptName, SysDept::getParentId);
        // wrapper.eq(SysDept::getDeptStatus, KoiConstants.ZERO_STRING);
        // List<SysDept> deptList = sysDeptService.list(wrapper);
        map.put("deptList", deptList);

        // 部门是否展开数据
        LambdaQueryWrapper<SysDept> lambdaWrapper = new LambdaQueryWrapper<>();
        lambdaWrapper.select(SysDept::getDeptId);
        lambdaWrapper.eq(SysDept::getIsSpread, KoiConstants.ZERO_STRING);
        lambdaWrapper.eq(SysDept::getDeptStatus, KoiConstants.ZERO_STRING);
        List<SysDept> deptSpreadList = sysDeptService.list(lambdaWrapper);
        List<String> spreadList = deptSpreadList.parallelStream().map(SysDept::getDeptId).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(spreadList)) {
            spreadList = new ArrayList<>();
        }
        map.put("spreadList", spreadList);
        return map;
    }

    /**
     * @description [根据用户拥有的角色ID查询部门权限数据]
     * @author ･ᴗ･
     */
    @GetMapping("/sysDept/listDeptIdsByRoleId/{roleId}")
    public List<String> listDeptIdsByRoleId(@PathVariable("roleId") Long roleId) {
        return sysDeptService.listDeptIdsByRoleId(roleId);
    }

    /**
     * @description [保存角色和部门权限之间的关系]
     * @author ･ᴗ･
     */
    @KoiLog(title = "分配部门", operType = OperType.AUTH)
    @SaCheckPermission("system:role:dept")
    @PostMapping("/sysDept/saveRoleDept/{roleId}/{deptIds}")
    public void saveRoleDept(@PathVariable("roleId") Long roleId, @PathVariable("deptIds") List<String> deptIds) {
        sysDeptService.saveRoleDept(roleId, deptIds);
    }

}
